package com.luqili.utils.pub.crypto;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.util.Random;

/**
 * AES加密工具类
 *
 * @author luqili
 */
public class AESEncrypt {

    /**
     * 加密字符串
     *
     * @param content
     * @param keyHex
     * @param charset
     * @return
     * @throws DecoderException
     */
    public static String encryptString(String content, String keyHex, Charset charset) {
        byte[] key;
        try {
            key = Hex.decodeHex(keyHex.toCharArray());
        } catch (DecoderException e) {
            throw AESException.createPrivateKey(e);
        }
        byte[] in = content.getBytes(charset);
        byte[] r = encrypt(in, key);
        return Base64.getEncoder().encodeToString(r);
    }

    /**
     * 解密字符串
     *
     * @param contentBase64
     * @param keyHex
     * @param charset
     * @return
     * @throws DecoderException
     */
    public static String decryptString(String contentBase64, String keyHex, Charset charset) {
        byte[] key;
        try {
            key = Hex.decodeHex(keyHex.toCharArray());
        } catch (DecoderException e) {
            throw AESException.createPrivateKey(e);
        }
        byte[] in = Base64.getDecoder().decode(contentBase64);
        byte[] r = decrypt(in, key);
        return new String(r, charset);
    }

    /**
     * AES加密
     *
     * @param in
     * @param key
     * @return
     */
    public static byte[] encrypt(byte[] in, byte[] key) {
        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密码器
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);
            return cipher.doFinal(in);
        } catch (Exception e) {
            throw AESException.createDecrypt(e);
        }
    }

    /**
     * AES解密
     *
     * @param in
     * @param key
     * @return
     */
    public static byte[] decrypt(byte[] in, byte[] key) {
        try {
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密码器
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec);
            return cipher.doFinal(in);
        } catch (Exception e) {
            throw AESException.createDecrypt(e);
        }
    }

    /**
     * 获得随机数组Hex编码
     *
     * @return
     */
    public static String getRandomKey128ToHex() {
        Random random = new SecureRandom();
        byte[] keys = new byte[16];
        random.nextBytes(keys);
        return new String(Hex.encodeHex(keys));
    }
}
